using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DatabaseCode.Data;

namespace DatabaseCode.Maker
{
  class DataioBaseMaker
  {
    public static string OutHeader(D1_Headers headers)
    {
      bool is_first;
      string str;
      D2_Header temp_h;
      str = @"
#ifndef COMMON_DATAIO_BASE_H_
#define COMMON_DATAIO_BASE_H_

#include <vector>

namespace dataio {

const int kTextSize = 64;
const int kLongTextSize  = 256;

class Enums {
public:

  enum Errors {
    kSuccess,            // 成功
    kNoneExistError,     // 存在しない（削除時）
    kUniqueError,        // 一意性制約エラー（追加時）
    kNoneReferenceError, // 必要な参照データがない（追加時）
    kReferencedError,    // 他から参照されている（削除時）
    kNoneTypeError       // 型が見つからない
  };

  enum Table {";
      is_first = true;
      foreach (D2_Header h in headers.Headers)
      {
        if(is_first)
        {
          is_first = false;
        }
        else
        {
          str += "\r\n";
        }
        foreach (D3_Table t in h.Tables)
        {
          str += "    k" + t.Name + ",\r\n";
        }
      }
      str += @"
    kTableNumber
  };
";
      is_first = true;
      foreach (D2_Header h in headers.Headers)
      {
        str += "  enum MgrDataMgrTable { \r\n";
        foreach (D3_Table t in h.Tables)
        {
          if (is_first)
          {
            is_first = false;
          }
          else
          {
            str += ",";
          }
          str += "\r\n    k" + t.Name + ", = kTable" + t.Name;
        }
        str += "  };\r\n";
      }
    str += @"
  enum Whos {";
      is_first = true;
      temp_h = null;
      foreach (D2_Header h in headers.Headers)
      {
        if(temp_h != null)
        {
          str += " // " + temp_h.Membername + ".h\r\n";
        }
        temp_h = h;
        if (is_first)
        {
          is_first = false;
        }
        else
        {
          str += ",";
        }
        str += "    k" + h.Name;
      }
      if(temp_h != null)
      {
        str += "  // " + temp_h.Membername + ".h\r\n";
      }
      str += @"
  };

  static Whos GetWhos(Table table);
};

template <class T>
struct Table {
 public:
  std::vector<T> table;

  int Size() { return table.size(); };
  int TypeSize() { return sizeof(T); };
  T& At(int pos) { return table[pos]; };

  // １件追加する。
  Enums::Errors Add(const T& record)
  {
    for (std::vector<T>::iterator it = table.begin(); it != table.end(); ++it)
    {
      if (record.IsEqualKey(*it)) {
        return Enums::kUniqueError;
      }
    }
    data_.push_back(data);
    return Enums::kSuccess;
  }

  // １件削除する。
  Enums::Errors Remove(const T& key)
  {
    for (std::vector<T>::iterator it = table.begin(); it != table.end(); ++it)
    {
      if (key.IsEqualKey(*it)) {
        data_.erase(it);
        return Enums::kSuccess;
      }
    }
    return Enums::kNoneExistError;
  }

  // 要素へのポインタを取得する。
  Enums::Errors GetPointer(const T& key, T&* ptr)
  {
    for (std::vector<T>::iterator it = table.begin(); it != table.end(); ++it)
    {
      if (key.IsEqualKey(*it)) {
        ptr = &*it;
        return Enums::kSuccess;
      }
    }
    return Enums::kNoneExistError;
  }
};

}  //  namespace dataio

#endif // COMMON_DATAIO_BASE_H_
";
      return str;
    }
    public static string OutSource(D1_Headers headers)
    {
      string str;
      D2_Header header;
      str = @"#include ""dataio_base.h""
#include <assert.h>

namespace dataio {

Enums::Whos Enums::GetWhos(Table table)
{
  switch (table)
  {
";
      foreach (D2_Header h in headers.Headers)
      {
        foreach (D3_Table t in h.Tables)
        {
          str += "  case kTable" + t.Name + ":\r\n";
        }
        str += "    return k" + h.Name + ";\r\n\r\n";
      }
      str += @"  }

  assert(false);
  return ";
      header = null;
      foreach (D2_Header h in headers.Headers)
      {
        header = h;
        break;
      }
      if (header == null)
      {
        str += "マネージャ名がありません。";
      }
      else
      {
        str += "k" + header.Name;
      }
      str += @";
}

}  //  namespace dataio";
      return str;
    }
  }
}
